package com.shunda.consumer.service.impl;

import com.google.code.kaptcha.Producer;
import com.shunda.common.constant.CacheConstants;
import com.shunda.common.constant.Constants;
import com.shunda.common.constant.UserConstants;
import com.shunda.common.core.domain.entity.SysDept;
import com.shunda.common.core.domain.entity.SysUser;
import com.shunda.common.core.domain.model.LoginUser;
import com.shunda.common.core.page.TableDataInfo;
import com.shunda.common.core.redis.RedisCache;
import com.shunda.common.utils.DateUtils;
import com.shunda.common.utils.StringUtils;
import com.shunda.common.utils.bean.BeanUtils;
import com.shunda.common.utils.ip.IpUtils;
import com.shunda.common.utils.sendMsg.SendMsgUtil;
import com.shunda.consumer.domain.ConsumerUser;
import com.shunda.consumer.domain.LoginConsumerUser;
import com.shunda.consumer.mapper.ConsumerUserMapper;
import com.shunda.consumer.service.IConsumerUserService;
import com.shunda.framework.web.service.TokenService;
import com.shunda.trade.controller.TradeOrderController;
import com.shunda.trade.controller.TradeWithdrawalsFlowController;
import com.shunda.trade.entity.TradeOrder;
import com.shunda.trade.entity.TradeWithdrawalsFlow;
import com.shunda.trade.service.CustomerStationsRecordService;
import com.shunda.trade.service.TradeProfitFlowService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.shunda.common.constant.UserConstants.NOT_UNIQUE;
import static com.shunda.common.constant.UserConstants.UNIQUE;

/**
 * @author: dongyq
 * @date: 2025/3/8 17:30
 * @since: 1.0.0
 * @功能描述:
 */
@Service
public class ConsumerUserServiceImpl implements IConsumerUserService {

    private static final Logger log = LoggerFactory.getLogger(ConsumerUserServiceImpl.class);

    @Autowired
    private ConsumerUserMapper consumerUserMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private CustomerStationsRecordService customerStationsRecordService;

    @Autowired
    private TradeOrderController tradeOrderController;

    @Autowired
    private TradeWithdrawalsFlowController tradeWithdrawalsFlowController;

    @Autowired
    private TradeProfitFlowService tradeProfitFlowService;

    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Override

    public boolean checkUserNameUnique(String userName) {
        if (consumerUserMapper.checkUserNameUnique(userName) > 0) {
            return NOT_UNIQUE;
        }
        return UNIQUE;
    }

    @Override
    public boolean checkPhoneUnique(String phone) {
        if (consumerUserMapper.checkPhoneUnique(phone) > 0) {
            return NOT_UNIQUE;
        }
        return UNIQUE;
    }

    @Override
    public ConsumerUser selectConsumerUserByPhone(String phone) {
        return consumerUserMapper.selectConsumerUserByPhone(phone);
    }

    @Override
    public ConsumerUser selectConsumerUserById(Long consumerId) {
        return consumerUserMapper.selectConsumerUserById(consumerId);
    }

    @Override
    public int insertTo(ConsumerUser consumerUser) {
        initConsumerUserDefaultValue(consumerUser);
        return consumerUserMapper.insertTo(consumerUser);
    }

    public void initConsumerUserDefaultValue(ConsumerUser consumerUser) {
        consumerUser.setUserType(UserConstants.CONSUMER_USER_TYPE);
        consumerUser.setSex("2");
        consumerUser.setRegisterTime(DateUtils.getNowDate());
        if (StringUtils.isEmpty(consumerUser.getNickName())) {
            consumerUser.setNickName(consumerUser.getUserName());
        }
    }

    @Override
    public int updateTo(ConsumerUser consumerUser, LoginConsumerUser loginConsumerUser) {
        if (loginConsumerUser != null) {
            consumerUser.setLoginIp(loginConsumerUser.getLoginIp() == null ? IpUtils.getIpAddr() : loginConsumerUser.getLoginIp());
            consumerUser.setLoginDate(DateUtils.getNowDate());
        }
        return consumerUserMapper.updateTo(consumerUser);
    }

    @Override
    public String loginGetToken(ConsumerUser consumerUser) {
        String phone = consumerUser.getPhonenumber();
        String webUserTokenKey = getWebUserTokenKey(phone);
        String token = null;
        if (consumerUser.getUserId() != null && consumerUser.getUserId() > 0) {
            LoginUser loginUser = new LoginUser();
            loginUser.setToken(phone);
            SysUser sysUser = new SysUser();
            BeanUtils.copyBeanProp(sysUser, consumerUser);
            loginUser.setUser(sysUser);
            loginUser.setDeptId(consumerUser.getDeptId());
            loginUser.setUserId(consumerUser.getUserId());
            loginUser.setLoginTime(System.currentTimeMillis());
            loginUser.setExpireTime(System.currentTimeMillis() +
                    Long.parseLong(UserConstants.WEB_USER_TOKEN_EXPIRATION) * Constants.ONE_DAY_MILLISECONDS);
            token = tokenService.createWebToken(loginUser);
            redisCache.setCacheObject(webUserTokenKey, loginUser, Integer.valueOf(UserConstants.WEB_USER_TOKEN_EXPIRATION), TimeUnit.DAYS);
        }
        return token;
    }

    @Override
    public List<SysDept> selectRecordByPhoneAndTop(String phone, int top) {
        Long userId = consumerUserMapper.selectConsumerUserIdByPhone(phone);
        return customerStationsRecordService.selectRecordByUserIdAndTop(userId, top);
    }

    @Override
    public TableDataInfo selectOrderPageByPhone(String phone) {
        Long userId = consumerUserMapper.selectConsumerUserIdByPhone(phone);
        TradeOrder tradeOrder = new TradeOrder();
        tradeOrder.setUserId(userId);
        return tradeOrderController.getOrderPage(tradeOrder);
    }

    @Override
    public TableDataInfo selectWithdrawPageByPhone(String phone) {
        Long userId = consumerUserMapper.selectConsumerUserIdByPhone(phone);
        TradeWithdrawalsFlow withdrawalsFlow = new TradeWithdrawalsFlow();
        withdrawalsFlow.setUserId(userId);
        return tradeWithdrawalsFlowController.getWithdrawFlowPage(withdrawalsFlow);
    }

    @Override
    public List<SysUser> selectSalesmanList(Long deptId) {
        ConsumerUser user = new ConsumerUser();
        user.setDeptId(deptId);
        return consumerUserMapper.selectSalesmanListByParams(user);
    }

    @Override
    public BigDecimal selectFundPoolTotalAmount() {
        return tradeProfitFlowService.selectUserFundPoolTotalAmount();
    }

    @Override
    public void getCaptcha(String phone) throws Exception {
        // 保存验证码信息
        String verifyKey = getWebCodeKey(phone);
        Boolean hasKey = redisCache.hasKey(verifyKey);
        if (hasKey) {
            throw new RuntimeException("验证码已发送，请稍后2分钟后再试！");
        }
        // 生成验证码
        String code = captchaProducer.createText();
        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        boolean sendSMS = SendMsgUtil.sendSMS(phone, code);
        if (!sendSMS) {
            //redisCache.deleteObject(verifyKey);// TODO 后续需要放开
            throw new RuntimeException("验证码发送失败，请联系管理员！");
        }
    }

    public void verifyCode(String phone, String code) throws Exception {
        String verifyKey = getWebCodeKey(phone);
        Boolean hasKey = redisCache.hasKey(verifyKey);
        if (hasKey) {
            String redisCode = redisCache.getCacheObject(verifyKey).toString();
            // 校验验证码
            if (redisCode.equals(code)) {
                // 删除验证码
                redisCache.deleteObject(verifyKey);
            } else {
                throw new RuntimeException("验证码错误！");
            }
        } else {
            throw new Exception("无效验证码！");
        }
    }

    @Override
    public void loginOut(LoginConsumerUser consumerUser) {
        String phone = consumerUser.getPhonenumber();
        String webUserTokenKey = getWebUserTokenKey(phone);
        Boolean hasKey = redisCache.hasKey(webUserTokenKey);
        if (hasKey) {
            // 删除Token
            redisCache.deleteObject(webUserTokenKey);
        }
    }

    public String getWebUserTokenKey(String phone) {
        return CacheConstants.LOGIN_TOKEN_KEY + phone;
    }

    public String getWebCodeKey(String phone) {
        return CacheConstants.CAPTCHA_CODE_KEY + phone;
    }
}
